package com.fkdx.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fkdx.common.dto.sys.CurrentUserDTO;
import com.fkdx.common.dto.sys.UserRoleDTO;
import com.fkdx.common.enums.SysStatusEnum;
import com.fkdx.common.enums.sys.GroupException;
import com.fkdx.common.sys.SecurityHelper;
import com.fkdx.common.token.TokenDomain;
import com.fkdx.common.token.TokenUtil;
import com.fkdx.common.utils.BeanUtil;
import com.fkdx.common.utils.VerifyCodeUtils;
import com.fkdx.dao.condition.PermissionCondition;
import com.fkdx.dao.condition.RoleCondition;
import com.fkdx.dao.condition.UserCondition;
import com.fkdx.dao.entity.*;
import com.fkdx.dao.mapper.PermissionMapper;
import com.fkdx.dao.mapper.RoleMapper;
import com.fkdx.dao.mapper.UserMapper;
import com.fkdx.dao.mapper.UserRoleMapper;
import com.fkdx.service.dto.*;
import com.google.common.collect.Lists;
import com.qcloud.cos.utils.Md5Utils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author: create by wsh 
 * @date:2022/8/20
 */
@Log4j2
@Service()
public class UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private TokenUtil tokenUtil;

    public TokenDomain login(UserLoginReq req) {
        User user = userMapper.selecUserByUserName(req.getUserName());
        log.info("用户{}", JSON.toJSONString(user));
        if (null == user) {
            throw new GroupException("用户名或密码错误!");
        }
        String reqPassword = getMd5Pwd(req.getPassword(), user.getSalt());
        if (!reqPassword.equals(user.getPassword())) {
            throw new GroupException("用户名或密码错误!");
        }
        CurrentUserDTO userInfo = new CurrentUserDTO();
        BeanUtils.copyProperties(user, userInfo);
        //查询用户角色
        RoleCondition condition = new RoleCondition();
        condition.setUserId(userInfo.getId());
        List<Role> roleList = roleMapper.queryList(condition);
        if (null == roleList || roleList.size() <= 0) {
            throw new GroupException("您无权限登录该平台!");
        }
        for (Role r : roleList) {
            if (r.getIsAdmin() == 1) {
                userInfo.setIsCustom(r.getIsAdmin());
                break;
            }
        }
        List<UserRoleDTO> roles = BeanUtil.copyListProperties(roleList, UserRoleDTO::new);
        userInfo.setRoles(roles);


        TokenDomain tokenDomain = tokenUtil.createToken(req.getUserName(), userInfo, true);
        tokenDomain.setUsername(req.getUserName());
        tokenDomain.setName(user.getName());
        tokenDomain.setVersion(1);
        tokenDomain.setId(user.getId());
        tokenDomain.setTenantId(user.getTenantId());
        tokenDomain.setPhone(user.getPhone());
        tokenDomain.setIntegral(user.getIntegral());
        return tokenDomain;
    }

    /**
     *      *     * @param req     * @return
     */
    public PageResult<UserQueryResp> getUserList(UserQueryReq req) {
        CurrentUserDTO principal = SecurityHelper.getPrincipal();
        UserCondition condition = new UserCondition();
        BeanUtils.copyProperties(req, condition);
        condition.setTenantId(principal.getTenantId());
        List<User> list = userMapper.selectAll(condition);
        PageResult<UserQueryResp> results = new PageResult<>(list, (m) -> {
            UserQueryResp res = new UserQueryResp();
            BeanUtils.copyProperties(m, res);
            return res;
        });
        return results;
    }

    /**
     * 获取详情     *     * @param id     * @return
     */
    public UserQueryResp getUserForm(Long id) {
        UserQueryResp resp = new UserQueryResp();
        User User = userMapper.selectByPrimaryKey(id);
        BeanUtils.copyProperties(User, resp);
        return resp;
    }

    /**
     * 新增、修改     *     * @param req
     */
    @Transactional(rollbackFor = GroupException.class)
    public void saveUserForm(UserReq req) {
        User User = new User();
        BeanUtils.copyProperties(req, User);
        if (req.getId() == null) {
            User UserData = userMapper.selecUserByUserName(User.getUserName());
            if (null != UserData) {
                throw new GroupException("用户名已存在!");
            }
            String pwd = req.getPassword();
            if (StringUtils.isBlank(pwd)) {
                pwd = "123456";
            }
            String salt = VerifyCodeUtils.getSecurityCode();
            String password = getMd5Pwd(pwd, salt);
            User.setPassword(password);
            User.setSalt(salt);
            User.setYn(SysStatusEnum.YES.getStatus());
            User.setCreateUserId(SecurityHelper.getPrincipal().getId());
            User.setCreateUserName(SecurityHelper.getPrincipal().getUserName());
            User.setModificationUserId(SecurityHelper.getPrincipal().getId());
            User.setModificationUserName(SecurityHelper.getPrincipal().getUserName());
            userMapper.insert(User);
            req.setId(User.getId());
        } else {
            //删除用户对应角色
            List<Long> userIds = new ArrayList<>();
            userIds.add(User.getId());
            userRoleMapper.deleteByUserIds(userIds);

            if (StringUtils.isNotEmpty(req.getPassword())) {
                String salt = VerifyCodeUtils.getSecurityCode();
                String password = getMd5Pwd(req.getPassword(), salt);
                User.setPassword(password);
                User.setSalt(salt);
                User.setModificationUserId(SecurityHelper.getPrincipal().getId());
                User.setModificationUserName(SecurityHelper.getPrincipal().getUserName());
            }
            if(req.getAddIntegral() != null || req.getSubIntegral() != null) {
                User old = userMapper.selectByPrimaryKey(req.getId());
                Integer integral = (old.getIntegral() != null ? old.getIntegral() : 0);
                if (req.getAddIntegral() != null) {
                    integral = integral + req.getAddIntegral();
                }
                if (req.getSubIntegral() != null) {
                    integral = integral - req.getSubIntegral();
                }
                User.setIntegral(integral);
            }
            userMapper.updateByPrimaryKey(User);
        }

        //新增用户角色
        UserRole UserRole = new UserRole();
        UserRole.setRoleId(req.getRoleId());
        UserRole.setUserId(User.getId());
        userRoleMapper.insert(UserRole);
    }

    /**
     * 删除     *     * @param id
     */
    @Transactional
    public void removeUserList(Long[] id) {
        userMapper.updateByIds(
                Lists.newArrayList(id),
                SecurityHelper.getPrincipal().getId(),
                SecurityHelper.getPrincipal().getUserName()
        );
        userRoleMapper.deleteByUserIds(Lists.newArrayList(id));
    }

    public String getMd5Pwd(String pwd, String salt) {
        if (StringUtils.isBlank(pwd) || StringUtils.isBlank(salt)) {
            throw new GroupException("参数不能为空!");
        }
        return Md5Utils.md5Hex(salt + pwd + salt);
    }

    public List<PermissionQueryResp> getUserPermission() {
        List<UserRoleDTO> roles = SecurityHelper.getPrincipal().getRoles();
        List<Long> roleIds = roles.stream().map(UserRoleDTO::getId).collect(Collectors.toList());
        PermissionCondition condition = new PermissionCondition();
        condition.setInitiate(false);
        condition.setRoleIds(roleIds);
        List<Permission> permissionList = permissionMapper.queryList(condition);
        log.info("权限获取{}", JSON.toJSONString(permissionList));
        return BeanUtil.copyListProperties(permissionList, PermissionQueryResp::new);
    }

  public List<UserQueryResp> getAll(UserQueryReq req) {
      UserCondition condition = new UserCondition();
      BeanUtils.copyProperties(req, condition);
      condition.setTenantId(SecurityHelper.getPrincipal().getTenantId());
      List<User> list = userMapper.selectAll(condition);
      List<UserQueryResp> results = new ArrayList<>();
      if (list != null && !list.isEmpty()) {
          list.stream().forEach(m -> {
              UserQueryResp res = new UserQueryResp();
              BeanUtils.copyProperties(m, res);
              results.add(res);
          });
      }
      return results;
  }

  public List<UserQueryResp> queryUserList(UserQueryReq req) {
      UserCondition condition = new UserCondition();
      condition.setLimit(100);
      List<User> list = userMapper.queryList(condition);
      List<UserQueryResp> results = new ArrayList<>();
      if (list != null && !list.isEmpty()) {
          list.stream().forEach(m -> {
              UserQueryResp res = new UserQueryResp();
              BeanUtils.copyProperties(m, res);
              results.add(res);
          });
      }
      return results;
  }

    public List<RoleQueryResp> roleALL() {
        RoleCondition condition = new RoleCondition();
        condition.setInitiate(false);
        List<Role> list = roleMapper.selectAll(condition);
        List<RoleQueryResp> results = new ArrayList<>();
        if (list != null && !list.isEmpty()) {
            list.stream().forEach(m -> {
                RoleQueryResp res = new RoleQueryResp();
                BeanUtils.copyProperties(m, res);
                results.add(res);
            });
        }
        return results;
    }

    @Transactional(rollbackFor = GroupException.class)
    public void modify(UserReq req) {
        User userData = userMapper.selecUserByUserName(req.getUserName());
        if (userData == null) {
            throw new GroupException("无账号");
        }
        String oldPassword = getMd5Pwd(req.getOldPassword(), userData.getSalt());
        String password = getMd5Pwd(req.getPassword(), userData.getSalt());
        if (!oldPassword.equals(userData.getPassword())) {
            throw new GroupException("旧密码错误");
        }
        if (password.equals(userData.getPassword())) {
            throw new GroupException("密码无变化");
        }
        User user = new User();
        BeanUtils.copyProperties(req, user);
        user.setPassword(password);
        userMapper.updateSelective(user);
    }

    public void modifyInfo(UserReq req) {
        User userData = userMapper.selecUserByUserName(req.getUserName());
        if (userData == null) {
            throw new GroupException("无账号");
        }
        User user = new User();
        BeanUtils.copyProperties(req, user);
        Integer integral = (userData.getIntegral() != null ? userData.getIntegral() : 0);
        if (req.getAddIntegral() != null) {
            integral = integral + req.getAddIntegral();
        }
        if (req.getSubIntegral() != null) {
            integral = integral - req.getSubIntegral();
        }
        user.setIntegral(integral);
        userMapper.updateSelective(user);
        if (req.getRoleId() != null) {
            //删除用户对应角色
            List<Long> userIds = new ArrayList<>();
            userIds.add(user.getId());
            userRoleMapper.deleteByUserIds(userIds);
            //新增用户角色
            UserRole UserRole = new UserRole();
            UserRole.setRoleId(req.getRoleId());
            UserRole.setUserId(user.getId());
            userRoleMapper.insert(UserRole);
        }
    }

    public void resetPwd(UserReq req) {
        User userData = userMapper.selectByPrimaryKey(req.getId());
        if (userData == null) {
            throw new GroupException("账号不存在");
        }
        String password = getMd5Pwd(req.getPassword(), userData.getSalt());
        User user = new User();
        BeanUtils.copyProperties(req, user);
        user.setPassword(password);
        userMapper.updateSelective(user);
    }

    public Integer getIntegral(String userName) {
        User user = userMapper.selecUserByUserName(userName);
        if (user != null && user.getIntegral() != null) {
            return user.getIntegral();
        }
        return 0;
    }
}
